package org.linlinjava.litemall.wx.web;

import cn.binarywang.wx.miniapp.api.WxMaService;
import cn.binarywang.wx.miniapp.bean.WxMaCodeLineColor;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.linlinjava.litemall.core.util.CharUtil;
import org.linlinjava.litemall.core.util.ResponseUtil;
import org.linlinjava.litemall.core.util.WithdrawEnum;
import org.linlinjava.litemall.db.domain.*;
import org.linlinjava.litemall.db.service.*;
import org.linlinjava.litemall.db.service.distribution.*;
import org.linlinjava.litemall.db.vo.TeamVo;
import org.linlinjava.litemall.wx.annotation.LoginUser;
import org.linlinjava.litemall.wx.util.DateTools;
import org.linlinjava.litemall.wx.util.IdUtil;
import org.linlinjava.litemall.wx.util.NewImageUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.io.Resource;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;

import java.awt.image.BufferedImage;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.math.BigDecimal;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.nio.file.StandardCopyOption;
import java.time.LocalDateTime;
import java.util.*;

@RestController
@RequestMapping("/wx/distribute")
public class WxDistributeController {
    private final Log logger = LogFactory.getLog(WxDistributeController.class);

    @Autowired
    private DisMemberInfoService memberService;
    @Autowired
    private DisMemberAmountService amountService;
    @Autowired
    private DisProfitRecordService recordService;
    @Autowired
    private DisWithdrawRecordService withdrawRecordService;
    @Autowired
    private LitemallOrderService orderService;
    @Autowired
    private LitemallUserService userService;
    @Autowired
    private WxMaService wxMaService;

    @Autowired
    private LitemallStorageService storageService;
    @Autowired
    private DisQrCodeService qrCodeService;

    /**
     * 获取用户分销信息
     */
    @GetMapping("/distributionCenter")
    public Object distributionCenter(@LoginUser Integer userId) {
        Map<String,Object> result = new HashMap<>();
        try {
            if (userId == null) {
                return ResponseUtil.unlogin();
            }
            //推荐人
            LitemallUser referee = new LitemallUser();
            DisMemberInfo memberInfo = memberService.getByUserId(userId);
            if (memberInfo != null && StringUtils.isNotBlank(memberInfo.getDisModelId())) {
                referee =  userService.findById(Integer.parseInt(memberInfo.getDisModelId()));
            }else{
                referee = new LitemallUser();
                referee.setNickname("总店");
            }
            result.put("referee",referee);
            //全部 已提现 可提现 元
            DisMemberAmount amount = amountService.getByuserId(userId);
            if(amount==null){
                amount = new DisMemberAmount();
            }
            result.put("amount",amount);
            //分销订单 笔
            Integer frofitCount = recordService.countByUserId(userId);
            result.put("frofitCount",frofitCount);
            //提现笔数
            Integer drawCount =  withdrawRecordService.countByUserId(userId);
            result.put("drawCount",drawCount);
            //团队  人

            List<TeamVo>  list = memberService.getTeamList( userId, 0);
            Integer count1 = memberService.getTeamCount(userId);
            List<TeamVo> returnList = new ArrayList<>();
            for(TeamVo v : list){
                List<TeamVo>  l = memberService.getTeamList( v.getUserId(), 0);
                returnList.addAll(l);
            }
            result.put("memCount",count1+returnList.size());
        } catch (Exception e) {
            e.printStackTrace();
            return ResponseUtil.fail(500,e.getMessage());
        }
        return ResponseUtil.ok(result);
    }
    /**
     * 获取用户余额
     */
    @GetMapping("/getPrice")
    public Object getPrice(@LoginUser Integer userId) {
        DisMemberAmount amount = new DisMemberAmount();
        try {
            if (userId == null) {
                return ResponseUtil.unlogin();
            }
            //全部 已提现 可提现 元
            amount = amountService.getByuserId(userId);
            if(amount==null){
                amount = new DisMemberAmount();

            }
        } catch (Exception e) {
            e.printStackTrace();
            return ResponseUtil.fail(500,e.getMessage());
        }
        return ResponseUtil.ok(amount);
    }
    /**
     * 用户提现
     */
    @PostMapping("/cash")
    public Object getPrice(@LoginUser Integer userId,@RequestBody Map<String,String> map) {
        try {
            if (userId == null) {
                return ResponseUtil.unlogin();
            }
            //提现 账户表  1设置冻结金额（审核通过后计入已提现） 2可提现金额-提现金额
            //根据登陆用户查找账户
            String cash = map.get("cash");
            String type = map.get("type");//类型
            String mobile = map.get("mobile");//提现账号
            String name = map.get("name");//真实姓名
            DisMemberAmount amount = amountService.getByuserId(userId);
            BigDecimal b = new BigDecimal(cash);
            //检查是否可提现
            BigDecimal result = amount.getAvaibleAmount().subtract(b);
            if(result.compareTo(new BigDecimal(0))>=0){
                //可提现
                String now = DateTools.getCurrentSysData(DateTools.FULLTIME_FORMAT);
                amount.setAvaibleAmount(amount.getAvaibleAmount().subtract(b));
                amount.setFrozenAmount(amount.getFrozenAmount().add(b));
                amount.setUpdateTime(now);
                amountService.update(amount);
                //增加提现记录
                DisWithdrawRecord withdrawRecord  = new DisWithdrawRecord();
                withdrawRecord.setDisUserId(userId);
                withdrawRecord.setTotalAmount(b);
                withdrawRecord.setWithdrawTime(now);
                withdrawRecord.setWithdrawStatus(WithdrawEnum.examine.getCode());
                withdrawRecord.setWithdrawNum(IdUtil.getId());
                withdrawRecord.setDisProType(type);
                withdrawRecord.setDisProMode(mobile);
                withdrawRecord.setDisProName(name);
                withdrawRecordService.insert(withdrawRecord);

            }else{
                return ResponseUtil.fail(401,"提现失败，账户可提现余额不足。");
            }
        } catch (Exception e) {
            e.printStackTrace();
            return ResponseUtil.fail(500,e.getMessage());
        }
        return ResponseUtil.ok("提现成功");
    }
     /**
     * 获取用户分销列表
     */
    @GetMapping("/getOrderList")
    public Object getOrderList(@LoginUser Integer userId,@RequestParam("page") Integer page,@RequestParam("status")String status) {
        List<DisProfitRecord> list = new ArrayList<>();
        try {
            if (userId == null) {
                return ResponseUtil.unlogin();
            }
            list = recordService.getOrderList( userId, page, status);

        } catch (Exception e) {
            e.printStackTrace();
            return ResponseUtil.fail(500,e.getMessage());
        }
        return ResponseUtil.ok(list);
    }
    /**
     * 获取团队
     */
    @GetMapping("/getTeamList")
    public Object getTeamList(@LoginUser Integer userId,@RequestParam("page") Integer page,@RequestParam("status") Integer status) {
        List<TeamVo> returnList = new ArrayList<>();
        Map<String,Object> returnMap = new HashMap<>();
        try {
            if (userId == null) {
                return ResponseUtil.unlogin();
            }
            //获取人数
            List<TeamVo>  list = memberService.getTeamList( userId, 0);
            Integer count1 = memberService.getTeamCount(userId);
            List<TeamVo> listTwo = new ArrayList<>();
            for(TeamVo v : list){
                List<TeamVo>  l = memberService.getTeamList( v.getUserId(), 0);
                listTwo.addAll(l);
            }
            returnMap.put("count1",count1);
            returnMap.put("count2",listTwo.size());

            //下线
            List<TeamVo>  teamList = memberService.getTeamList( userId, page);
            if(status==2){
                //二级
                Integer start = (page-1)*5;
                if(start>listTwo.size()){
                    listTwo.clear();
                  return ResponseUtil.ok(returnList);
                }
                Integer end = page*5;
                if(end>listTwo.size()){
                    end = listTwo.size();
                }
                returnList = listTwo.subList(start,end);
            }else{
                returnList.clear();
                returnList.addAll(teamList);
            }
            //订单数量
            returnList.forEach(teamVo -> {
                List<LitemallOrder> orderList = orderService.queryByEnd(teamVo.getUserId());
                Integer orderCount = orderList.size();
                teamVo.setOrderNum(orderCount);
                //消费额度
                BigDecimal amount = new BigDecimal(0);
                for(LitemallOrder order:orderList){
                  amount = amount.add(order.getActualPrice());
                };
                teamVo.setAmount(amount);
            });
        } catch (Exception e) {
            e.printStackTrace();
            return ResponseUtil.fail(500,e.getMessage());
        }
        returnMap.put("list",returnList);
        return ResponseUtil.ok(returnMap);
    }

    /**
     * 获取用户提现列表
     */
    @GetMapping("/getCashList")
    public Object getCashList(@LoginUser Integer userId,@RequestParam("page") Integer page,@RequestParam("status") String status) {
        List<DisWithdrawRecord> list = new ArrayList<>();
        try {
            if (userId == null) {
                return ResponseUtil.unlogin();
            }
             list = withdrawRecordService.selecByUserId(userId,page,status);
            list.forEach(record->{
                record.setWithdrawStatusName(WithdrawEnum.getNameByCode(record.getWithdrawStatus()));
            });
        } catch (Exception e) {
            e.printStackTrace();
            return ResponseUtil.fail(500,e.getMessage());
        }
        return ResponseUtil.ok(list);
    }

    /**
     * 新增推荐人记录
     */
    @GetMapping("/memberInfo")
    public Object memberInfo(@LoginUser Integer userId,@RequestParam("pUserId") String pUserId) {
        List<DisWithdrawRecord> list = new ArrayList<>();
        try {
            //创建非会员账号  如果存在并有推荐人不操作，无推荐人则更新，不存在 新增
            LitemallUser user = userService.findById(userId);
            if(user==null){
               return ResponseUtil.fail(404,"用户不存在。");
            }
            DisMemberInfo memberInfo = memberService.getByUserId(userId);
            if(memberInfo!=null){
                if(StringUtils.isBlank(memberInfo.getDisModelId())){
                    memberInfo.setDisModelId(pUserId);
                    memberInfo.setUpdateTime(DateTools.getCurrentSysData(DateTools.FULLTIME_FORMAT));
                    memberService.update(memberInfo);
                }
            }else{
                memberInfo = new DisMemberInfo();
                memberInfo.setDisUserId(userId.toString());
                memberInfo.setDisUserName(user.getNickname());
                memberInfo.setDisModelId(pUserId);
                memberInfo.setType(DisMemberInfo.TYPE_N);
                memberInfo.setIsDelete("N");
                memberInfo.setAddTime(DateTools.getCurrentSysData(DateTools.FULLTIME_FORMAT));
                memberInfo.setUpdateTime(DateTools.getCurrentSysData(DateTools.FULLTIME_FORMAT));
                memberService.add(memberInfo);
            }
        } catch (Exception e) {
            e.printStackTrace();
            return ResponseUtil.fail(500,e.getMessage());
        }
        return ResponseUtil.ok(list);
    }

    /**
     * 查看用户是否能提现
     */
    @GetMapping("/isMember")
    public Object IsMember(@LoginUser Integer userId) {
        DisMemberInfo memberInfo = new DisMemberInfo();
        try {
            if (userId == null) {
                return ResponseUtil.unlogin();
            }
            memberInfo = memberService.getByUserId(userId);
            if(memberInfo!=null && DisMemberInfo.TYPE_Y.equals(memberInfo.getType())){
                return ResponseUtil.ok(true);
            }else{
                return ResponseUtil.ok(false);
            }
        } catch (Exception e) {
            e.printStackTrace();
            return ResponseUtil.fail(500,e.getMessage());
        }
    }
    /**
     * 推广二维码
     */
    @GetMapping("/getCodeUnlimit")
    public Object getCodeUnlimit(@LoginUser Integer userId) {
        try {
            if (userId == null) {
                return ResponseUtil.unlogin();
            }
           DisQrCode qrCode = qrCodeService.getByUserId(userId);
            if(qrCode!=null){
                return ResponseUtil.ok(qrCode);
            }else{
                String sourceFilePath = "/usr/images/template.jpg";
                WxMaCodeLineColor color = new WxMaCodeLineColor("0","0","0");
                File file =   wxMaService.getQrcodeService().createWxaCodeUnlimit(userId.toString(),"pages/index/index",380,false,color,false);
                String originalFilename = file.getName();
                String key = generateKey(originalFilename);
                //TODO usr/images/qr
                String saveFilePath = "/usr/images/"+key;
                System.out.println(file.getPath());
                NewImageUtils newImageUtils = new NewImageUtils();
                //构建叠加层
                BufferedImage buffImg = NewImageUtils.watermark(new File(sourceFilePath), file, 180, 380, 1f);
                //输出水印图片
                File lastFile = newImageUtils.generateWaterFile(buffImg, saveFilePath);
                //file.delete();


//                InputStream inputStream = null;
//                try {
//                    inputStream = new FileInputStream(lastFile);
//                } catch (IOException e) {
//                    e.printStackTrace();
//                    return ResponseUtil.badArgumentValue();
//                }
//
//                /
//                Files.copy(inputStream, Paths.get(saveFilePath).resolve(originalFilename), StandardCopyOption.REPLACE_EXISTING);

                String url = "/fetch/"+ key;

                LitemallStorage storageInfo = new LitemallStorage();
                storageInfo.setName(originalFilename);
                storageInfo.setSize(1);
                storageInfo.setType("image/jpeg");
                storageInfo.setAddTime(LocalDateTime.now());
                storageInfo.setModified(LocalDateTime.now());
                storageInfo.setKey(key);
                storageInfo.setUrl(url);
                storageService.add(storageInfo);
                DisQrCode qr = new DisQrCode();
                qr.setAddTime(new Date());
                qr.setName(originalFilename);
                qr.setUrl(url);
                qr.setUserid(userId);
                qrCodeService.add(qr);
                return ResponseUtil.ok(qr);
            }
        } catch (Exception e) {
            e.printStackTrace();
            logger.error("",e);
            return ResponseUtil.fail(500,e.getMessage());
        }
    }
    @GetMapping("/fetch/{key:.+}")
    public ResponseEntity<Resource> fetch(@PathVariable String key) {
        LitemallStorage litemallStorage = storageService.findByKey(key);
        if(key == null){
            ResponseEntity.notFound();
        }
        String type = litemallStorage.getType();
        MediaType mediaType = MediaType.parseMediaType(type);

        Resource file = storageService.loadAsResource(key);
        if(file == null) {
            ResponseEntity.notFound();
        }
        return ResponseEntity.ok().contentType(mediaType).body(file);
    }
    private String generateKey(String originalFilename){
        int index = originalFilename.lastIndexOf('.');
        String suffix = originalFilename.substring(index);

        String key = null;
        LitemallStorage storageInfo = null;

        do{
            key = CharUtil.getRandomString(20) + suffix;
            storageInfo = storageService.findByKey(key);
        }
        while(storageInfo != null);

        return key;
    }
    public static void main(String[] args) {
        List<Integer> returnList = new ArrayList<>();
        returnList.add(1);
        returnList.add(2);
        returnList.add(3);
        returnList.add(4);
        returnList.add(5);
        returnList.add(6);
        returnList.add(7);
        returnList.add(8);
        returnList.add(9);
        returnList.add(10);
        returnList.add(11);
        returnList.add(12);
        returnList.add(13);
        returnList.add(14);
        returnList.add(15);
        Integer page=4;
        Integer start = (page-1)*5;
        Integer end = page*5;
        if(end>returnList.size()){
            end = returnList.size();
        }

        System.out.println(returnList.subList(start,end));
    }
}